package com.lry.basic.algorithm.flow.windows;


public class SlidingTimeWindows {

    private int slot;

    private long limit;

    private Node lastNode;

    private long slotTime;

    public SlidingTimeWindows(int slot, long limit) {
        this.slot = slot;
        this.limit = limit;
        init();
    }

    private void init(){
        Node curNode = null;
        long cur = System.currentTimeMillis();

        for(int i=0;i<slot;i++){
            if(null==lastNode){
                lastNode = new Node(cur,0,i+1);
                curNode = lastNode;
            }else{
                lastNode.next = new Node(cur,0,i+1);
                lastNode = lastNode.next;
            }
        }
        lastNode.next = curNode;
        slotTime = 1000 / slot;
    }
    public synchronized boolean checkAndAdd(){
        reset();
        long sum = getSum();
        System.out.println(sum);
        if(sum>=limit){
            return false;
        }
        lastNode.addCounter();
        return true;
    }

    private void reset(){
        long curTime = System.currentTimeMillis();
        long time = lastNode.getTime();
        int count = (int) ((curTime-time)/slotTime);
        if(count>slot){
            count = slot;
        }
        reset(count,curTime);
    }

    private void reset(int num,long curTime){
        if(num<=0){
            return;
        }
        Node curNode = lastNode;
        for(int i=0;i<num;i++){
            curNode = curNode.next;
        }
        curNode.setTime(curTime);
        curNode.setCounter(0L);
        lastNode = curNode;
    }

    private long getSum(){
        long sum = 0L;
        Node curNode = lastNode;
        for(int i=0;i<slot;i++){
            sum+=curNode.getCounter();
            curNode = curNode.next;
        }
        return sum;
    }


}
